package com.smile.frame.common.util;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author LGC
 * @date 2021/11/18 18:58

 */
public class FrameDateUtil {
    public static void main(String[] args) throws ParseException {
        Date date = getBeforeDate(1);
        System.out.println(DateUtil.format(date, DatePattern.NORM_DATETIME_PATTERN));


        System.out.println(getAfterDateStrList(14));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        //获取两个区间内 为 周7的所有日期
        List<String> dayOfWeekWithinDateInterval = getDayOfWeekWithinDateInterval("2021-11-01", "2021-11-30", 0);
        System.out.println("获取两个区间内 为 周7的所有日期 : " + dayOfWeekWithinDateInterval);

        // 指定日期加上 *  天  算出结束日期   备注  注意看调用这个方法的执行注释  这个4 和7  的区别，4为4周。7天为一周
        String endDate = selectBeginAndEndDate("2021-11-01", 1);
        System.out.println("指定日期加上 *  天  算出结束日期 : " + endDate);
        //结果： 2021-01-11

        //这个是算出两个日期区间内，的所有日期
        List<String> dates = getBeginAndEndDateBetween("2020-12-14", "2021-01-11");
        System.out.println(dates);

        //指定日期，推算计算出这个日期为： 周几？星期几？
        String week = getWeek(sdf.parse("2020-12-14"));
        System.out.println("指定日期，推算计算出这个日期为 : " + week);
        //结果 ： 周一

        //区间内，计算多个周数的日期集合
        String scheduleWeek = "2,4";
        List<String> strings = Arrays.asList(scheduleWeek.split(","));

//        //2、使用：得出集合日期 - 不排班的日期  = 获取区间内要排班的所有日期
        Collection<String> scheduleRuleDateList = new ArrayList<>();
        for (String dayWeek : strings) {
//            List<String> dayOfWeekWithinDateInterva12 = getDayOfWeekWithinDateInterval("2020-12-14", endDate, Integer.parseInt(dayWeek));
            List<String> dayOfWeekWithinDateInterva12 = getDayOfWeekWithinDateInterval("2020-12-14", "2021-01-11", Integer.parseInt(dayWeek));
            scheduleRuleDateList.addAll(dayOfWeekWithinDateInterva12);
        }
        System.out.println("指定日期 + 周数 算出区间内所有日期  得出集合日期 : " + scheduleRuleDateList);


    }

    /**
     * 指定日期；算出指定 * 某多少天数的日期
     *
     * @param startDate
     * @param weekNum
     */
    public static String selectBeginAndEndDate(String startDate, long weekNum) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            weekNum = weekNum * 7 - 1;    // - 注意一点，* 7 这个暂时使用到这个为周数的，如果换成天或月或年。相对应要改变。-1：起始日期算 1 天+7 = 8天  -1是结束日期宿回一天，使用起始日期顶
            Date date = sdf.parse(startDate); // 指定日期
            long time = date.getTime(); // 得到指定日期的毫秒数
            weekNum = weekNum * 24 * 60 * 60 * 1000; // 要加上的天数转换成毫秒数
            time += weekNum; // 相加得到新的毫秒数
            return sdf.format(new Date(time)); // 将毫秒数转换成日期
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 指定起始日期 ： 指定结束日期 ：指定周几 ，算出区间内指定周几的日期
     *
     * @param dateBegin
     * @param dateEnd
     * @param week
     */
    public static List<String> getDayOfWeekWithinDateInterval(String dateBegin, String dateEnd, int week) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<String> dateResult = new ArrayList<>();   //如果要换成日期类型的这里定义
//        List<Date> dateResult = new ArrayList<>();   //如果要换成日期类型的这里定义
        Calendar cal = Calendar.getInstance();
        String[] dateInterval = {dateBegin, dateEnd};
        Date[] dates = new Date[dateInterval.length];
        for (int i = 0; i < dateInterval.length; i++) {
            String[] ymd = dateInterval[i].split("[^\\d]+");
            cal.set(Integer.parseInt(ymd[0]), Integer.parseInt(ymd[1]) - 1, Integer.parseInt(ymd[2]));
            dates[i] = cal.getTime();
        }
        for (Date date = dates[0]; date.compareTo(dates[1]) <= 0; ) {
            cal.setTime(date);
            if (cal.get(Calendar.DAY_OF_WEEK) - 1 == week) {
                String format = sdf.format(date);  //控制为 返回什么类型的 相反即可
                dateResult.add(format);  //控制为 返回什么类型的 相反即可
//                dateResult.add(date);
            }
            cal.add(Calendar.DATE, 1);
            date = cal.getTime();
        }
        return dateResult;
    }


    /**
     * 指定日期：算出指定日期是周几或是星期几
     *
     * @param date
     */
    public static String getWeek(Date date) {
//        String[] weeks = {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
        String[] weeks = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"};
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int week_index = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (week_index < 0) {
            week_index = 0;
        }
        return weeks[week_index];
    }

    /**
     * 获取两个日期之间的所有日期
     *
     * @param beginDate 开始日期
     * @param endDate   结束日期
     * @return List集合
     */
    public static List<String> getBeginAndEndDateBetween(String beginDate, String endDate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<String> list = new ArrayList<String>(); //保存日期的集合
        Date date_start = sdf.parse(beginDate);
        Date date_end = sdf.parse(endDate);
        Date date = date_start;
        Calendar cd = Calendar.getInstance();//用Calendar 进行日期比较判断
        while (date.getTime() <= date_end.getTime()) {
            list.add(sdf.format(date));
            cd.setTime(date);
            cd.add(Calendar.DATE, 1);//增加一天 放入集合
            date = cd.getTime();
        }
        return list;
    }

    /**
     * 当天指定n天后日期，包含当天
     *
     * @param days
     * @return
     */
    public static List<String> getAfterDateStrList(Integer days) {
        List<String> dates = new ArrayList<>();
        dates.add(DateUtil.formatDate(new Date()));
        Calendar calendar = null;
        for (Integer i = 1; i < days; i++) {
            calendar = Calendar.getInstance();
            calendar.add(Calendar.DATE, i);
            dates.add(DateUtil.formatDate(calendar.getTime()));
        }
        return dates;
    }

    /**
     * 当天指定n天后日期，包含当天
     *
     * @param days
     * @return
     */
    public static List<Date> getAfterDateList(Integer days) {
        List<Date> dates = new ArrayList<>();
        dates.add(new Date());
        Calendar calendar = null;
        for (Integer i = 1; i < days; i++) {
            calendar = Calendar.getInstance();
            calendar.add(Calendar.DATE, i);
            dates.add(DateUtil.parseDate(DateUtil.formatDate(calendar.getTime())));
        }
        return dates;
    }

    /**
     * 获取当天最后时间
     *
     * @return
     */
    public static Date getTodayFinallyDate() {
        Date today = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(today);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }

    /**
     * 当天指定n天前日期，包含当天
     *
     * @param day
     * @return
     */
    public static Date getBeforeDate(Integer day) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, -day);
        return DateUtil.parse(DateUtil.format(calendar.getTime(), "yyyy-MM-dd 23:59:59"));
    }


}
